from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.hashers import make_password, check_password
import uuid
# Create your models here.
class Permission(models.Model):
    class PermissionType(models.TextChoices):
        Menu = "menu", _("Menu")
        Button = "button", _("Button")
        MenuDir = "menu_dir", _("MenuDir")
    
    class PermissionMenuType(models.TextChoices):
        Tab = "tab", _("Tab")
        Link = "link", _("Link")
        Iframe = "iframe", _("Iframe")
    
    class PermissionExtend(models.TextChoices):
        none = "none", _("None")
        AddRulesOnly = "add_rules_only", _("AddRulesOnly")
        AddMenuOnly = "add_menu_only", _("AddMenuOnly")
    
    pid = models.IntegerField(default=0,db_index=True)  # Parent ID
    type = models.CharField(max_length=10,choices=PermissionType,default=PermissionType.Menu)  # Enum for permission type
    title = models.CharField(max_length=50, default="")  # Title of the permission
    name = models.CharField(max_length=50, default="",db_index=True)  # Name of the permission
    path = models.CharField(max_length=100, default="")  # Path for the permission
    addtab = models.BooleanField(default=False)
    icon = models.CharField(max_length=50, default="")  # Icon for the menu item
    menu_type = models.CharField(max_length=10,choices=PermissionMenuType,null=True,blank=True)  # Type of the menu
    url = models.CharField(max_length=255, null=True, blank=True)  # URL for the permission
    keepalive = models.BooleanField(default=False)  # Whether the permission is keepalive
    extend = models.CharField(max_length=20,choices=PermissionExtend,default=PermissionExtend.none)  
    remark = models.TextField(null=True, blank=True)  # Remark for the permission
    weigh = models.IntegerField(default=0)  # Weigh of the permission
    status = models.BooleanField(default=True)  # Status of the permission
    updatetime = models.DateTimeField(auto_now=True)  # Last update time

    class Meta:
        verbose_name = _("Permission")
        verbose_name_plural = _("Permissions")
        ordering = ['id']

    def __str__(self):
        return self.name
    
class App(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4,db_index=True, unique=True) #应用编号

    name = models.CharField(max_length=100, db_index=True) #应用名称
    app_key = models.TextField() #应用密钥
    app_secret = models.TextField() #应用密钥
    app_desc = models.CharField(max_length=200, default="") #应用描述
    app_status = models.BooleanField(default=True) #应用状态
    app_create_time = models.DateTimeField(auto_now_add=True) #创建时间
    app_update_time = models.DateTimeField(auto_now=True) #更新时间
    
    possess_permission = models.ManyToManyField(Permission, blank=True,editable=False,related_name='possess_permission') #拥有权限
    
    class Meta:
        verbose_name = _("App")
        verbose_name_plural = _("Apps")
        ordering = ['id']
    
    def __str__(self):
        return self.name
        
class Role(models.Model):
    app = models.ForeignKey(App, on_delete=models.CASCADE, null=True, blank=True,db_index=True,default=None)  # App of the role
    name = models.CharField(max_length=50, default="")  # Name of the role
    permissions = models.ManyToManyField(Permission, blank=True,editable=False)  # Permissions of the role
    remark = models.TextField(null=True, blank=True)  # Remark for the role
    weigh = models.IntegerField(default=0)  # Weigh of the role
    status = models.BooleanField(default=True)  # Status of the role
    updatetime = models.DateTimeField(auto_now=True)  # Last update time

    class Meta:
        verbose_name = _("Role")
        verbose_name_plural = _("Roles")
        ordering = ['id']

    def __str__(self):
        return self.name
    
class User(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4,db_index=True, unique=True)
    app = models.ForeignKey(App, on_delete=models.CASCADE, null=True, blank=True,db_index=True,default=None)  # App of the user
    is_suser = models.BooleanField(default=False)  # 可以管辖多个应用
    apps = models.ManyToManyField(App, blank=True,null=True,related_name='apps',editable=False)  # Apps of the user
    username = models.CharField(max_length=50, default="",db_index=True,unique=True)#登录用的名称
    username_show = models.CharField(max_length=50, default="",db_index=True)  # Username of the user    
    password = models.CharField(max_length=100, default="")  # Password of the user
    email = models.EmailField(max_length=255, null=True, blank=True)  # Email of the user
    roles = models.ManyToManyField(Role, blank=True,editable=False)  # Roles of the user
    permissions = models.ManyToManyField(Permission, blank=True,editable=False)  # Permissions of the user
    lastloginip = models.CharField(max_length=20, null=True, blank=True)  # Last login IP of the user
    lastlogintime = models.DateTimeField(null=True, blank=True)  # Last login time of the user
    remark = models.TextField(null=True, blank=True)  # Remark for the user
    weigh = models.IntegerField(default=0)  # Weigh of the user
    status = models.BooleanField(default=True)  # Status of the user
    updatetime = models.DateTimeField(auto_now=True)  # Last update time

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = []
    is_active = True

    @property
    def is_anonymous(self):
        """
        Always return False. This is a way of comparing User objects to
        anonymous users.
        """
        return False
    
    @property
    def is_authenticated(self):
        """
        Always return True. This is a way to tell if the user has been
        authenticated in templates.
        """
        return True

    def set_password(self, raw_password):
        self.password = make_password(raw_password)

    def check_password(self, raw_password):
        return check_password(raw_password, self.password)

    class Meta:
        verbose_name = _("User")
        verbose_name_plural = _("Users")
        ordering = ['id']

    def __str__(self):
        return self.username
